package com.ciaojian.worker.service;

import cn.hutool.core.date.DateUnit;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ciaojian.core.constant.RedisConstant;
import com.ciaojian.core.enums.business.OrderOrderTypeEnum;
import com.ciaojian.core.enums.business.OrderStatusEnum;
import com.ciaojian.core.mapper.OrderMapper;
import com.ciaojian.core.model.Order;
import com.ciaojian.core.model.OrderCouponRecord;
import com.ciaojian.core.model.Worker;
import com.ciaojian.core.model.vo.MyOrderVO;
import com.ciaojian.core.model.vo.StoreMonthGapVo;
import com.ciaojian.core.model.vo.StoreRealPerformanceVo;
import com.ciaojian.core.service.OrderCommentService;
import com.ciaojian.core.service.OrderService;
import com.ciaojian.core.util.DateUtil;
import com.ciaojian.core.util.RedisUtil;
import com.ciaojian.core.util.Result;
import com.ciaojian.core.util.TimeUtil;
import com.ciaojian.worker.model.param.BadCommentParam;
import com.sun.org.apache.bcel.internal.generic.NEW;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 剪发订单 服务类
 *
 * @author Atlakyn
 */
@Service
public class OrderServiceImpl extends OrderService<OrderMapper, Order> {
    @Resource
    private OrderMapper orderMapper;
    private final static Logger payLogger = LoggerFactory.getLogger("pay");
    @Resource
    private OrderCouponRecordServiceImpl orderCouponRecordService;
    @Resource
    private WorkerServiceImpl workerService;
    @Resource
    private OrderCommissionServiceImpl orderCommissionService;
    @Resource
    private OrderCommentService orderCommentService;

    /**
     * 获取发型师差评订单
     *
     * @param param 参数
     * @return 发型师差评订单
     */
    public Page<Map<String, Object>> getBadComment(BadCommentParam param) {
        return orderMapper.getBadComment(new Page<>(param.getPageNo(), param.getPageSize()),
                param.getWorkerId(),
                param.getDate());
    }

    /**
     * 开始服务
     *
     * @param order 订单
     */
    public void startService(Order order) {
        order.setStatus(OrderStatusEnum.servicing);
        order.setStartServiceTime(new Date());
        order.setServiceTime(DateUtil.now());
        order.updateById();
        // 存入开始服务时间
        RedisUtil.setKeyTime(RedisConstant.WORKER_START_SERVING_TIME + order.getId(), 3600, DateUtil.now(),DateUnit.SECOND);
    }

    public Page<MyOrderVO> getMyOrder(Date startDate,
                                      Date endDate,
                                      Integer workerId,
                                      Integer orderType,
                                      Integer pageNo,
                                      Integer pageSize) {
        Page<MyOrderVO> pageOrder = orderMapper.getMyOrder(new Page<>(pageNo, pageSize), startDate, endDate, orderType, workerId, pageNo);
        pageOrder.getRecords().forEach(order -> {
            order.setOrderCouponRecords(orderCouponRecordService.lambdaQuery()
                    .eq(OrderCouponRecord::getOrderId, order.getOrderId()).list());
            Integer memBerCount = workerService.getBaseMapper().getMemBerCount(order.getUserId().toString());
            if (memBerCount > 0) {
                order.setIsMember(1);
            } else {
                order.setIsMember(0);
            }
        });
        return pageOrder;
    }

    /**
     * 锁单操作
     * 对已经支付但是还未收到微信回调的接口进行锁单
     *
     * @param orderId 订单 id
     * @return 锁单结果
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean lockOrder(Integer orderId) {
        UpdateWrapper<Order> wrapper = new UpdateWrapper<>();
        wrapper.set("status", 21)
                .eq("id", orderId)
                .in("status", 1, 2);
        return this.update(wrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    public void payNotify(Order order) {
        payLogger.info(">>>payNotify,修改前的订单={}>>>", order.toString());
        // 顾客当前订单之前已完成和已支付的订单数
        Integer count = this.countNumberOfComplete(order);
        //更新订单状态（status改为3：已支付 ）
        order.setStatus(OrderStatusEnum.paid);
        order.setPayType("微信支付-现金");
        order.setPayTime(new Date());
        order.setPayTotal(order.getGoodsTotal());
        this.setCustomerType(order);
        order.updateById();

        // 剪发新增提成记录
        orderCommissionService.insert(order);

        payLogger.info(">>>payNotify,修改后的订单={}>>>", order);
    }

    public BigDecimal calDiscount(Order order, String code, String type, Integer memberDiscountId, BigDecimal money, Integer userIdOfOrder) {
        return null;
    }

    /**
     * 发型师完成剪发订单
     *
     * @param order 剪发订单
     */
    public Long complete(Order order) {
        order.setStatus(OrderStatusEnum.wait_pay);
        Date currentDate = new Date();
        order.setEndServiceTime(currentDate);
        order.updateById();

        // 计算开始时间到结束时间的差值
        return DateUtil.between(order.getStartServiceTime(), currentDate, DateUnit.MINUTE);
    }


    public Result getStorePerformance(Integer storeId, Date startTime, Date endTime){
        StoreRealPerformanceVo storeRealPerformanceVo = new StoreRealPerformanceVo();

        // 实际业绩
        BigDecimal sumTotal = orderMapper.storeAmountCount(storeId, startTime, endTime);
        if (sumTotal!=null) {
            sumTotal = sumTotal.setScale(2,BigDecimal.ROUND_HALF_DOWN);
        }else {
            sumTotal = new BigDecimal(0);
        }

        // 本月订单数
        Integer orderCount = orderMapper.orderCount(storeId, startTime, endTime);

        //本月会员数
        Integer customerNum = orderMapper.customerNum(storeId, startTime, endTime);

        //剪发订单数
        Integer cutHairNum = orderMapper.countCutHairNum(storeId, 1,startTime, endTime);

        // 会员订单(新/老)
        Map<String, Integer> newAndOldMemberNum = orderMapper.countNewAndOldMember(storeId,null,startTime, endTime);

        // 差评数
        Integer badCommentNum = orderCommentService.countComment(storeId, null, 1, startTime, endTime);

        // 新人优惠订单
        Integer newCustomerNum = orderMapper.countNewCustomerNum(storeId, null, startTime, endTime);

        // 抖音订单数
        Integer douyinNum = orderMapper.countCutHairNum(storeId, 4,startTime, endTime);

        // 抖音销售
        BigDecimal amountDouyin = new BigDecimal(douyinNum);
        if (amountDouyin!=null&&douyinNum!=0){
            BigDecimal bigDecimal = new BigDecimal(9.9);
            amountDouyin = amountDouyin.multiply(bigDecimal);
            amountDouyin = amountDouyin.setScale(2,BigDecimal.ROUND_HALF_DOWN);
        }else {
            amountDouyin = new BigDecimal(0);
        }

        String newCustomer = newAndOldMemberNum.get("newCustomer").toString();
        Integer newC = Integer.parseInt(newCustomer);
        String oldCustomer = newAndOldMemberNum.get("oldCustomer").toString();
        Integer oldC = Integer.parseInt(oldCustomer);

        storeRealPerformanceVo.setSumTotal(sumTotal);
        storeRealPerformanceVo.setOrderCount(orderCount);
        storeRealPerformanceVo.setCustomerNum(customerNum);
        storeRealPerformanceVo.setNewCustomer(newC);
        storeRealPerformanceVo.setOldCustomer(oldC);
        storeRealPerformanceVo.setCutHairNum(cutHairNum);
        storeRealPerformanceVo.setBadCommentNum(badCommentNum);
        storeRealPerformanceVo.setNewCustomerNum(newCustomerNum);
        storeRealPerformanceVo.setDouyinNum(douyinNum);
        storeRealPerformanceVo.setAmountDouyin(amountDouyin);

        return Result.ok(storeRealPerformanceVo);
    }

    public List<Worker> listByStoreId(Integer storeId, Date startDate, Date endDate){
        return orderMapper.listByStoreId(storeId,startDate,endDate);
    }

    public Result getStoreMonthGap(Integer storeId, String startTimeStr) throws ParseException {
        //控制时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");

        Date startTime = simpleDateFormat.parse(startTimeStr);

        Calendar endCalendar = Calendar.getInstance();
        Calendar startCalendar = Calendar.getInstance();

        startCalendar.setTime(startTime);
        endCalendar.setTime(startTime);

        Date endTime = new Date();

        //开始时间前两个月
        startCalendar.add(Calendar.MONTH, -2);
        startTime = startCalendar.getTime();

        //结束时间
        endCalendar.add(Calendar.MONTH, +1);
        endCalendar.add(Calendar.MINUTE, -1);
        endTime = endCalendar.getTime();

        List<StoreMonthGapVo> storeMonthGapVoList = orderMapper.getStoreMonthGap(storeId, startTime, endTime);

        //三个月数据
        StoreMonthGapVo storeMonthGapVoIndex1 = storeMonthGapVoList.get(0);
        StoreMonthGapVo storeMonthGapVoIndex2 = storeMonthGapVoList.get(1);
        StoreMonthGapVo storeMonthGapVoIndex3 = storeMonthGapVoList.get(2);

        //三个月分别的总业绩
        double total1 = storeMonthGapVoIndex1.getTotal().doubleValue();
        double total2 = storeMonthGapVoIndex2.getTotal().doubleValue();
        double total3 = storeMonthGapVoIndex3.getTotal().doubleValue();

        //对比上个月比
        double cacheTotal1 = (total1-total2)/total2*100;
        double cacheTotal2 = (total2-total3)/total3*100;

        storeMonthGapVoList.get(0).setStatus(cacheTotal1>0 ? 0:1);
        storeMonthGapVoList.get(1).setStatus(cacheTotal2>0 ? 0:1);

        //小数点处理
        DecimalFormat format = new DecimalFormat("#.0");
        String str = format.format(cacheTotal1);
        cacheTotal1 = Double.parseDouble(str);
        str = format.format(cacheTotal2);
        cacheTotal2 = Double.parseDouble(str);


        //封装
        storeMonthGapVoList.get(0).setRatio(Math.abs(cacheTotal1));
        storeMonthGapVoList.get(1).setRatio(Math.abs(cacheTotal2));

        storeMonthGapVoList.remove(2);

        return Result.ok(storeMonthGapVoList);
    }
}
